package com.geor.gcv.core.mat;

import java.util.List;
import java.util.Properties;

import org.opencv.core.Mat;
import org.slf4j.Logger;

import com.geor.common.log.Loggers;
import com.geor.gcv.core.model.Area;

/**
 * 瀑布法(增强)字符分割器实现
 * 
 * @author geor.yuli
 * 
 */
public class CellChipperFallsImpl implements CellChipper {

	static Logger log = Loggers.get();
	
	CellChipper cellChipper = new CellChipperFallImpl();

	@Override
	public List<Area> execute(Mat mat) throws Exception {
		
		Mat mirror = null;
		try {
			// 顶端切分
			List<Area> areas = cellChipper.execute(mat);
			
			// 取镜像
			mirror = getVtcMirror(mat);
			
			// 再切分一次
			List<Area> mirrorAreas = cellChipper.execute(mirror);
			// TODO Y变换
			int height = mat.rows();
			for (Area mirrorArea : mirrorAreas) {
				mirrorArea.setY(height - mirrorArea.getY() - mirrorArea.getHeight());
			}
			
			if (areas.size() > mirrorAreas.size()) return areas;
			if (areas.size() < mirrorAreas.size()) return mirrorAreas;
			
			// 判断最优
			int originOffset = getWidthOffset(areas);
			int mirrorOffset = getWidthOffset(mirrorAreas);
			
			return (originOffset <= mirrorOffset) ? areas : mirrorAreas;
			
		} finally {
			if (null != mirror) {
				Mats.releseMat(mirror);
			}
		}
	}

	@Override
	public void setParams(Properties properties) {
	}
	
	/**
	 * 累计区域间宽度变化的绝对值
	 * @param areas
	 * @return
	 */
	private int getWidthOffset(List<Area> areas) {
		int offset = 0;
		for (int i = 1; i < areas.size(); i++) {
			offset += Math.abs(areas.get(i).getWidth() - areas.get(i - 1).getWidth());
		}
		return offset;
	}
	
	/**
	 * 获取垂直镜像
	 * @param mat
	 * @return
	 */
	private Mat getVtcMirror(Mat mat) {
		Mat mirror = Mat.zeros(mat.rows(), mat.cols(), mat.type());
		for (int i = 0; i < mat.rows(); i++) {
			for (int j = 0; j < mat.cols(); j++) {
				mirror.put(mat.rows() - 1 - i, j, mat.get(i, j));
			}
		}
		return mirror;
	}
	
}
